package com.yf.dxapp.module.app.component.app;

import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.yf.dxapp.module.app.controller.admin.course.vo.CoursePageReqVO;
import com.yf.dxapp.module.app.controller.app.vo.AppCourseItemVo;
import com.yf.dxapp.module.app.controller.app.vo.AppCourseVo;
import com.yf.dxapp.module.app.controller.app.vo.CourseListRequest;
import com.yf.dxapp.module.app.controller.app.vo.ListResult;
import com.yf.dxapp.module.app.dal.dataobject.appuser.AppUserDO;
import com.yf.dxapp.module.app.dal.dataobject.course.CourseDO;
import com.yf.dxapp.module.app.dal.dataobject.courseitem.CourseItemDO;
import com.yf.dxapp.module.app.enums.ErrorCodeConstants;
import com.yf.dxapp.module.app.enums.app.AppCourseHotEnum;
import com.yf.dxapp.module.app.enums.app.AppYesNoNum;
import com.yf.dxapp.module.app.enums.app.LevelEnum;
import com.yf.dxapp.module.app.service.appuser.AppUserService;
import com.yf.dxapp.module.app.service.course.CourseService;
import com.yf.dxapp.module.app.service.courseitem.CourseItemService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yxmds
 */
@Slf4j
@Component
public class AppCourseComponent {

    private static final String DEFAULT_USER_NAME = "";
    private static final String DEFAULT_USER_AVATAR = "";
    @Resource
    private CourseService appCourseService;

    @Resource
    private CourseItemService appCourseItemService;

    @Resource
    private AppUserService userService;

    @Resource
    private QiniuFileComponent qiniuFileComponent;

    public AppCourseVo getDouxinCourseVo(Long courseId, Long loginUserId) {
        log.info("查询课程信息，courseId={}", courseId);
        // step1. 通过courseId 查询课程
        CourseDO dxCourse = appCourseService.getCourse(courseId);
        if (dxCourse == null) {
            return null;
        }

        if (loginUserId != null) {
            AppUserDO userEntity = userService.getAppUser(loginUserId);
            if (userEntity != null && dxCourse.getLevelId() < userEntity.getLevelId()) {
                throw new ServiceException(ErrorCodeConstants.BUSINESS_ERROR.getCode(), "用户级别过低，请联系客服调整级别");
            }
        } else if (dxCourse.getLevelId() < LevelEnum.YK.levelId) {
            throw new ServiceException(GlobalErrorCodeConstants.FORBIDDEN.getCode(), "还未登录，请先登录");
        }

        AppCourseVo appCourseVo = convertCourse(dxCourse);
        // step2. 查询课程明细
        List<CourseItemDO> dxCourseItems = appCourseItemService.selectByCourseId(courseId);

        fillCourseItems(appCourseVo, dxCourseItems);

        return appCourseVo;
    }

    public ListResult<AppCourseVo> getCourseList(Long loginUserId, CourseListRequest request) {
        CoursePageReqVO query = buildQuery(loginUserId, request);
        PageResult<CourseDO> pageResult = appCourseService.getCoursePage(query);
        List<CourseDO> dxCourses = pageResult.getList();
        if (dxCourses.isEmpty()) {
            return new ListResult<>(Collections.emptyList(), false);
        }
        List<AppCourseVo> appCourseVoList = dxCourses.stream().map(dxCourse -> {
            AppCourseVo appCourseVo = convertCourse(dxCourse);
            return appCourseVo;
        }).collect(Collectors.toList());
        return new ListResult<>(appCourseVoList, request.getPage() * request.getLimit() <= pageResult.getTotal());
    }

    public ListResult<AppCourseVo> getMyCourseList(Long loginUserId, CourseListRequest request) {
        CoursePageReqVO query = buildMyCourseQuery(loginUserId, request);
        PageResult<CourseDO> pageResult = appCourseService.getCoursePage(query);
        List<CourseDO> dxCourses = pageResult.getList();
        if (dxCourses.isEmpty()) {
            return new ListResult<>(Collections.emptyList(), false);
        }
        List<AppCourseVo> appCourseVoList = dxCourses.stream().map(dxCourse -> {
            AppCourseVo appCourseVo = convertCourse(dxCourse);
            return appCourseVo;
        }).collect(Collectors.toList());
        return new ListResult<>(appCourseVoList, request.getPage() * request.getLimit() <= pageResult.getTotal());
    }

    public List<AppCourseVo> getSelectedCourseLit(Long loginUserId, Integer limit) {
        CoursePageReqVO query = new CoursePageReqVO();
        fillLevelPermission(query, loginUserId);
        query.setSelected(AppYesNoNum.YES.getIndex());
        PageResult<CourseDO> result = appCourseService.getCoursePage(query);
        return result.getList().stream().map(c -> convertCourse(c)).toList();
    }

    public List<AppCourseVo> getHotCourseLit(Long loginUserId, Integer limit) {
        CoursePageReqVO query = new CoursePageReqVO();
        fillLevelPermission(query, loginUserId);
        query.setHot(AppYesNoNum.YES.getIndex());
        PageResult<CourseDO> result = appCourseService.getCoursePage(query);
        return result.getList().stream().map(c -> convertCourse(c)).toList();
    }

    public List<AppCourseVo> getRecommendCourseLit(Long loginUserId, Integer limit) {
        CoursePageReqVO query = new CoursePageReqVO();
        fillLevelPermission(query, loginUserId);
        query.setRecommend(AppYesNoNum.YES.getIndex());
        PageResult<CourseDO> result = appCourseService.getCoursePage(query);
        return result.getList().stream().map(c -> convertCourse(c)).toList();
    }


    private CoursePageReqVO buildQuery(Long loginUserId, CourseListRequest courseListRequest) {
        CoursePageReqVO query = new CoursePageReqVO();
        fillLevelPermission(query, loginUserId);
        if (courseListRequest.getType() != null && courseListRequest.getType() > 0) {
            query.setCourseType(courseListRequest.getType());
        }
        query.setTitle(courseListRequest.getKeywords());
        query.setPageNo(courseListRequest.getPage());
        query.setPageSize(courseListRequest.getLimit());
        query.setPublisherId(courseListRequest.getPublisherId());
        query.setShelf(AppYesNoNum.YES.getIndex());
        return query;
    }


    private CoursePageReqVO buildMyCourseQuery(Long loginUserId, CourseListRequest courseListRequest) {
        CoursePageReqVO query = new CoursePageReqVO();
        fillLevelPermission(query, loginUserId);
        if (courseListRequest.getType() != null && courseListRequest.getType() > 0) {
            query.setCourseType(courseListRequest.getType());
        }
        query.setTitle(courseListRequest.getKeywords());
        query.setPageNo(courseListRequest.getPage());
        query.setPublisherId(courseListRequest.getPublisherId());
        query.setPageSize(courseListRequest.getLimit());


        if (loginUserId != null) {
            query.setBehaviorUserId(loginUserId);
        } else {
            query.setId(0L);
        }
        return query;
    }

    private void fillLevelPermission(CoursePageReqVO query, Long loginUserId) {
        if (loginUserId != null) {
            AppUserDO userEntity = userService.getAppUser(loginUserId);
            if (userEntity != null) {
                query.setMinLevelId(userEntity.getLevelId());
            }
        } else {
            // 用户级别越高，level数字越小，参考levelEnum
            query.setMinLevelId(LevelEnum.YK.levelId);
        }
    }

    public AppCourseVo convertCourse(CourseDO dxCourse) {
        AppCourseVo appCourseVo = new AppCourseVo();
        appCourseVo.setCourseShotCount(dxCourse.getCourseShotCount());
        appCourseVo.setCourseType(dxCourse.getCourseType());
        appCourseVo.setCover(qiniuFileComponent.complementFileUrl(dxCourse.getCover()));
        appCourseVo.setDescription(dxCourse.getDescription());
        appCourseVo.setId(dxCourse.getId());
        appCourseVo.setHot(Objects.equals(AppCourseHotEnum.YES.getIndex(), dxCourse.getHot()));
        appCourseVo.setTitle(dxCourse.getTitle());
        appCourseVo.setTotalTimes(dxCourse.getTotalTimes());
        appCourseVo.setItems(null);
        appCourseVo.setTotalWatchTimes(0L);
        appCourseVo.setLevelId(dxCourse.getLevelId());
        appCourseVo.setCreateTime(dxCourse.getCreateTime());
        appCourseVo.setCreator(dxCourse.getCreator());
        appCourseVo.setUpdater(dxCourse.getUpdater());
        appCourseVo.setUpdateTime(dxCourse.getUpdateTime());
        appCourseVo.setPublisherId(dxCourse.getPublisherId().toString());
        appCourseVo.setPublisher(dxCourse.getPublisherName());
        return appCourseVo;
    }

    private void fillCourseItems(AppCourseVo appCourseVo, List<CourseItemDO> dxCourseItems) {
        List<AppCourseItemVo> dxCourseVos = dxCourseItems.stream().map(item -> convert(item)).sorted(Comparator.comparing(c -> c.getCourseNo())).collect(Collectors.toList());
        // 填充发布人信息
        fillPublisherToList(dxCourseVos, dxCourseItems);
        appCourseVo.setItems(dxCourseVos);
        appCourseVo.setPublisher("张三");
    }

    private AppCourseItemVo convert(CourseItemDO dxCourseItem) {
        AppCourseItemVo appCusCourseItemVo = new AppCourseItemVo();
        appCusCourseItemVo.setCourseNo(dxCourseItem.getCourseNo());
        appCusCourseItemVo.setCourseNoStr(dxCourseItem.getCourseNoStr());
        appCusCourseItemVo.setCover(qiniuFileComponent.complementFileUrl(dxCourseItem.getCover()));
        appCusCourseItemVo.setDescription(dxCourseItem.getDescription());
        appCusCourseItemVo.setId(dxCourseItem.getId());
        appCusCourseItemVo.setTitle(dxCourseItem.getTitle());
        appCusCourseItemVo.setPublisherId(dxCourseItem.getPublisherId().toString());

        appCusCourseItemVo.setUrl(qiniuFileComponent.privateFileUrl(dxCourseItem.getUrl()));
        // TODO 观看数据单独获取
        appCusCourseItemVo.setWatchTimes(0);
        appCusCourseItemVo.setWatchViewers(0);
        appCusCourseItemVo.setTimes(dxCourseItem.getTime());
        return appCusCourseItemVo;
    }

    private void fillPublisherToList(List<AppCourseItemVo> dxCourseVos, List<CourseItemDO> dxCourseItems) {
        Set<Long> publisherIds = dxCourseItems.stream().map(CourseItemDO::getPublisherId).collect(Collectors.toSet());
        // 调用用户接口查询用户信息
        List<AppUserDO> userList = userService.finByUserIds(publisherIds);
        Map<Long, AppUserDO> usertMap = userList.stream().collect(Collectors.toMap(AppUserDO::getId, Function.identity()));
        dxCourseVos.forEach(item -> {
            Long publisherId = Long.parseLong(item.getPublisherId());
            if (!usertMap.containsKey(publisherId)) {
                item.setPublisher(DEFAULT_USER_NAME);
                item.setPublisherAvatar(DEFAULT_USER_AVATAR);
            }
            AppUserDO userEntity = usertMap.get(publisherId);
            if (userEntity != null) {
                item.setPublisher(userEntity.getName());
                item.setPublisherAvatar(userEntity.getAvatar());
            }
        });
    }

}
